package net.knightwatch.kwtools;

import net.knightwatch.kwtools.database.KwToolsDatasource;
import net.knightwatch.kwtools.walkthrough.items.Answer;
import net.knightwatch.kwtools.walkthrough.items.AutoCompleteAnswer;
import net.knightwatch.kwtools.walkthrough.items.BooleanAnswer;
import net.knightwatch.kwtools.walkthrough.items.Item;
import net.knightwatch.kwtools.walkthrough.items.ItemType;
import net.knightwatch.kwtools.walkthrough.items.PhotoAnswer;
import net.knightwatch.kwtools.walkthrough.items.Question;
import net.knightwatch.kwtools.walkthrough.items.RadioButtonAnswer;
import net.knightwatch.kwtools.walkthrough.items.SpinnerAnswer;
import net.knightwatch.kwtools.walkthrough.items.TextAnswer;
import android.app.Activity;
import android.content.Intent;
import android.database.SQLException;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Chronometer;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

public class ItemDetailActivity extends Activity {
	protected static final String TAG = "ItemDetailActivity";
	private Item item;
	// Used to store the last saved item to the database for comparison of changes.
	private KwToolsDatasource datasource = new KwToolsDatasource(this);
	private LinearLayout linearLayout;
	private Chronometer timer;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// Display a list of question for the selected object type. 
		// Answer the questions then save them back to the database. 
		super.onCreate(savedInstanceState);
		setContentView(R.layout.item_detail_activity);
		startTimer();
		setupItemFromIntent();
		setupItemSpecificInformation();
		// TODO create a new AsyncTask to query the database for questions.
		new QueryRootQuestionsTask().execute(item.getItemType());
	}

	@Override
	protected void onResume() {
		// TODO Item Detail Activity on Resume activity.
		super.onResume();

	}

	@Override
	protected void onStop() {
		// TODO Auto-generated method stub
		try {
			saveItem();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		super.onStop();
	}

	private class QueryRootQuestionsTask extends AsyncTask<Object, Void, Void> {

		protected void onPreExecute() {
			Log.d(TAG, "Started task to load root questions for the item type - onPreExecute()");
			Toast.makeText(ItemDetailActivity.this, "Loading Questions" , Toast.LENGTH_SHORT).show();
		}

		protected Void doInBackground(Object ... obj) {
			ItemType itemType = (ItemType) obj[0];
			// Query the database for the list of root questions for the item type
			datasource.Open();
			try{
				item.setQuestions(datasource.getItemQuestions(itemType));
			} catch (SQLException e) {
				e.printStackTrace();
			}
			datasource.Close();
			return null;
		}

		protected void onPostExecute(Void unused) {
			Log.d(TAG, "Generating the root questions - onPostExecute()");
			// Generate the list of questions after the data has been aquired.
			generateQuestions();
		}
	}
	private void setupItemSpecificInformation() {
		// TODO Setup Item Specific Information. Name, GPS
		TextView itemName = new TextView(this);
		EditText itemName_etxt = new EditText(this);
		itemName_etxt.setText(item.getName());
		itemName_etxt.setHint("Enter Item Name");
		itemName_etxt.addTextChangedListener(new TextWatcher(){

			public void afterTextChanged(Editable s) {
				// Set the name of the item to the string value after the text has changed.
				item.setName(s.toString());
			}

			public void beforeTextChanged(CharSequence s, int start, int count,
					int after) {
			}

			public void onTextChanged(CharSequence s, int start, int before,
					int count) {				
			}

		});
		// Add these view items to the layout. 
		linearLayout.addView(itemName);
		linearLayout.addView(itemName_etxt);
	}

	private void startTimer() {
		// Start the timer.
		timer = new Chronometer(this);
		timer.start();
	}

	private void setupItemFromIntent() {
		Log.d(TAG, "setupItemFromIntent()");
		// Set initial values
		item = new Item();
		// Set the customer that this item belongs
		Log.d(TAG, "customer id = " + getIntent().getLongExtra("customerId", -1));
		try{
			datasource.Open();
			if(getIntent().getLongExtra("itemId", -1)>0){
				Log.v(TAG, "Looking up the item from the database. ItemId = " + getIntent().getLongExtra("itemId", -1));
				item = datasource.getItem(getIntent().getLongExtra("itemId", -1));
			} else {
				Log.v(TAG, "Creating a new Item for the Potential. PotentialId = " + getIntent().getLongExtra("potentialId",  -1));
				item.setPotentialId(getIntent().getLongExtra("potentialId", -1));
			}
			item.setCustomer(datasource.getCustomer(getIntent().getLongExtra("customerId",-1)));
			item.setItemType(datasource.getItemType(getIntent().getLongExtra("itemTypeId",-1)));

		} catch (SQLException e){
			e.printStackTrace();
		} finally {
			datasource.Close();
		}
		setLinearLayout((LinearLayout) findViewById(R.id.itemDetailActivityLayout));
	}

	private void generateQuestions() {
		Log.d(TAG, "generateQuestions()");
		// Loop through the questions and return the view and setup event listeners
		for (int index=0; index < item.getQuestions().size(); index++) {
			final int tempIndex = index;
			Question q = this.item.getQuestions().get(index);
			// Build the question first looking at the type of answer that it is going to be. 
			switch(q.getAnswer().getAnswerTypeId()){
			case Answer.PHOTO_TYPE:
				Log.d(TAG, "PHOTO_TYPE event listeners being created");
				PhotoAnswer photoAnswer = (PhotoAnswer) q.getAnswer();
				linearLayout.addView(q.getLayout(this));
				photoAnswer.getButton().setOnClickListener(new View.OnClickListener() {
					public void onClick(View v) {
						// Open the camera intent when the camera button is pressed. 
						Log.d(TAG, "The index to match the photo to is "+tempIndex);
						Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
						startActivityForResult(cameraIntent, tempIndex);
					}
				});
				if(item.getItemId() > 0){
					// Look up the answer from the database.
					try {
						datasource.Open();
						PhotoAnswer fullAnswer = (PhotoAnswer) datasource.getAnswer(item.getItemId(), q.getQuestionId(), photoAnswer.getAnswerTypeId());
						photoAnswer.setAnswerId(fullAnswer.getAnswerId());
						photoAnswer.setPhoto(fullAnswer.getPhoto());
					} catch (Exception e){
						e.printStackTrace();
						Log.e(TAG, "Unable to retrieve the answer from the database");
					} finally { 
						datasource.Close();
					}
				}
				break;
			case Answer.AUTOCOMPLETE_TYPE:
				Log.d(TAG, "AUTOCOMPLETE_TYPE being created");
				AutoCompleteAnswer autoCompleteAnswer = (AutoCompleteAnswer) q.getAnswer();
				Log.d(TAG, "Hint Text for AutoComplete is "+autoCompleteAnswer.getHintText());

				try{
					datasource.Open();
					autoCompleteAnswer.setRecentAnswers(datasource.getRecentAnswerForCustomer(item.getCustomer().getCustomerId(), q.getQuestionId()));
					Log.d(TAG, "Set the list of recent answers for this customers question.");
				} catch (Exception e){
					Log.e(TAG, "Unable to get the answers from the database.");
				} finally {
					datasource.Close();
				}
				q.setAnswer(autoCompleteAnswer);
				linearLayout.addView(q.getLayout(this));
				if(item.getItemId()>0){
					// Look up the answer from the database
					try{
						datasource.Open();
						AutoCompleteAnswer fullAnswer = (AutoCompleteAnswer) datasource.getAnswer(item.getItemId(), q.getQuestionId(), autoCompleteAnswer.getAnswerTypeId());
						autoCompleteAnswer.setAnswerText(fullAnswer.getAnswer());
						autoCompleteAnswer.setAnswerId(fullAnswer.getAnswerId());
						autoCompleteAnswer.updateAnswerView();
					} catch (Exception e){
						e.printStackTrace();
					} finally {
						datasource.Close();
					}
				}
				break;
			default:
				this.linearLayout.addView(q.getLayout(this));
				if(item.getItemId()>0){
					// Lookup the answer from the database
					try{
						datasource.Open();
						Answer answer = datasource.getAnswer(item.getItemId(), q.getQuestionId(), q.getAnswer().getAnswerTypeId());
						q.getAnswer().setAnswerId(answer.getAnswerId());
						q.getAnswer().setAnswerText(answer.toString());
					} catch (Exception e){
						e.printStackTrace();
					} finally {
						datasource.Close();
					}
				}
			}

		}
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		try {
			if (requestCode > 0){
				Question q = item.getQuestions().get(requestCode);
				switch(q.getAnswer().getAnswerTypeId()){
				case Answer.PHOTO_TYPE:
					Log.d(TAG, "Matching back to photo index "+requestCode);
					PhotoAnswer photoAnswer;
					photoAnswer = (PhotoAnswer) q.getAnswer();
					photoAnswer.setPhoto(matchPhotoToAnswer(requestCode, data, photoAnswer));
				}
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			Log.e(TAG, "No Photo was taken");
			e.printStackTrace();
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu dependent on the mode.
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.item_detail_activity_menu, menu);
		return true;
	}
	// What to do when one of the options menus items in the action bar is pressed.
	@Override
	public boolean onOptionsItemSelected(MenuItem mitem) {
		switch(mitem.getItemId()){
		case(R.id.save):
			// Update the values of the potential
			// TODO Save the answers to the database.
			try {
				saveItem();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				Toast.makeText(this, "You must enter an Item name to be able to save.", Toast.LENGTH_SHORT).show();
				e.printStackTrace();
			}
		Toast.makeText(this, "Item has been saved to the database.", Toast.LENGTH_SHORT).show();
		break;
		case R.id.closeItem:
			finish();
			break;
		default:
			break;
		}
		return false;
	}

	private void saveItem() throws Exception {
		try {
			if(item.getName().isEmpty()){
				throw new Exception();
			}
			timer.stop();
			item.setTimeElapsedMillis(timer.getBase());
			Log.v(TAG, "Saving item to the database linked to the potential. It took " + item.getTotalTime(timer.getBase()));
			// Save the item to the database
			datasource.Open();
			if (item.getItemId() > 0){
				datasource.updateItem(item);
			} else {
				item = datasource.createItem(item);
			}

			if(item.getQuestions().size() > 0){
				for(Question q : item.getQuestions()){
					switch(q.getAnswer().getAnswerTypeId()){
					case Answer.PHOTO_TYPE:
						// save photo to database
						PhotoAnswer photoAnswer = new PhotoAnswer();
						photoAnswer = (PhotoAnswer) q.getAnswer();
						if(photoAnswer.getAnswerId() > 0){
							datasource.updatePhotoAnswer(item.getItemId(), item.getCustomer().getCustomerId(), q.getQuestionId(), photoAnswer);
						} else {
							photoAnswer.setAnswerId(datasource.createPhotoAnswer(item.getItemId(), item.getCustomer().getCustomerId(), q.getQuestionId(), photoAnswer));
						}
						break;
					case Answer.BOOLEAN_TYPE:
						// save boolean type to database
						BooleanAnswer booleanAnswer = new BooleanAnswer();
						booleanAnswer = (BooleanAnswer) q.getAnswer();
						if(booleanAnswer.getAnswerId() > 0){
							datasource.updateBooleanAnswer(item.getItemId(), item.getCustomer().getCustomerId(), q.getQuestionId(), booleanAnswer);
						} else {
							booleanAnswer.setAnswerId(datasource.createBooleanAnswer(item.getItemId(), item.getCustomer().getCustomerId(), q.getQuestionId(), booleanAnswer));
						}
						break;
					case Answer.TEXT_TYPE:
						// save Text Type to Database
						TextAnswer textAnswer = new TextAnswer();
						textAnswer = (TextAnswer) q.getAnswer();
						if(textAnswer.getAnswerId() > 0){
							datasource.updateTextAnswer(item.getItemId(), item.getCustomer().getCustomerId(), q.getQuestionId(), textAnswer);
						} else {
							textAnswer.setAnswerId(datasource.createTextAnswer(item.getItemId(), item.getCustomer().getCustomerId(), q.getQuestionId(), textAnswer));
						}
						break;
					case Answer.SPINNER_TYPE:
						// save Spinner Type to Database
						SpinnerAnswer spinnerAnswer = new SpinnerAnswer();
						spinnerAnswer = (SpinnerAnswer) q.getAnswer();
						if(spinnerAnswer.getAnswerId() > 0){
							datasource.updateSpinnerAnswer(item.getItemId(), item.getCustomer().getCustomerId(), q.getQuestionId(), spinnerAnswer);
						} else {
							spinnerAnswer.setAnswerId(datasource.createSpinnerAnswer(item.getItemId(), item.getCustomer().getCustomerId(), q.getQuestionId(), spinnerAnswer));
						}
						break;
					case Answer.RADIOBUTTON_TYPE:
						// save Radio Button to Database
						RadioButtonAnswer radioButtonAnswer = new RadioButtonAnswer();
						radioButtonAnswer = (RadioButtonAnswer) q.getAnswer();
						if(radioButtonAnswer.getAnswerId() > 0){
							datasource.updateRadioButtonAnswer(item.getItemId(), item.getCustomer().getCustomerId(), q.getQuestionId(), radioButtonAnswer);
						} else {
							radioButtonAnswer.setAnswerId(datasource.createRadioButtonAnswer(item.getItemId(), item.getCustomer().getCustomerId(), q.getQuestionId(), radioButtonAnswer));
						}
						break;
					case Answer.AUTOCOMPLETE_TYPE:
						// save Auto Complete to Database
						AutoCompleteAnswer autoCompleteAnswer = new AutoCompleteAnswer();
						autoCompleteAnswer = (AutoCompleteAnswer) q.getAnswer();
						if(autoCompleteAnswer.getAnswerId() > 0){
							datasource.updateAutoCompleteAnswer(item.getItemId(), item.getCustomer().getCustomerId(), q.getQuestionId(), autoCompleteAnswer);
						} else {
							autoCompleteAnswer.setAnswerId(datasource.createAutoCompleteAnswer(item.getItemId(), item.getCustomer().getCustomerId(), q.getQuestionId(), autoCompleteAnswer));
						}	
						break;
					default:
						break;
						// TODO save all text related feilds to the database.
					}
					Log.v(TAG, "Question: " + q.getQuestion() + " Answer: " + q.getAnswer().toString());
				}
			}

		} catch (SQLException e) {
			Toast.makeText(this,  "The item was not saved an sql error has occured.", Toast.LENGTH_SHORT).show();
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e){
			Log.w(TAG, "Item was not saved because item name was not entered");
		} finally {
			datasource.Close();
		}

	}

	private Bitmap matchPhotoToAnswer(int requestCode, Intent data, PhotoAnswer photoAnswer) {
		Log.v(TAG, "requestCode Match Found displaying the photo next to question");
		Bitmap photo = (Bitmap) data.getExtras().get("data"); 
		return photo;
	}

	public LinearLayout getLinearLayout() {
		return linearLayout;
	}


	public void setLinearLayout(LinearLayout linearLayout) {
		this.linearLayout = linearLayout;
	}

}